package com.leyou.item.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.leyou.common.exception.LyException;
import com.leyou.page.dto.PageDTO;
import com.leyou.item.dto.SkuDTO;
import com.leyou.item.dto.SpuDTO;
import com.leyou.item.dto.SpuDetailDTO;
import com.leyou.item.entity.*;
import com.leyou.item.mapper.SpuMapper;
import com.leyou.item.service.*;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class SpuServiceImpl extends ServiceImpl<SpuMapper, Spu> implements SpuService {

    @Autowired
    private BrandService brandService;
    @Autowired
    private CategoryService categoryService;
    @Autowired
    private SkuService skuService;
    @Autowired
    private SpuDetailService detailService;
    @Autowired
    private SpuService spuService;
    @Autowired
    private AmqpTemplate amqpTemplate;


    @Override
    public PageDTO<SpuDTO> querySpuByPage(Integer page, Integer rows, Boolean saleable, Long categoryId, Long brandId, Long id) {
        // 1.健壮性
        int current = Math.max(page, 1);
        int size = Math.max(rows, 5);

        //注入不为空的查询条件  查询spu表
        Page<Spu> result = query()
                .eq(saleable != null, "saleable", saleable)
                .eq(categoryId != null, "cid3", categoryId)
                .eq(brandId != null, "brand_id", brandId)
                .eq(id != null, "id", id)
                .page(new Page<>(current, size));


        // 4.解析查询结果
        long total = result.getTotal();  //总条数
        long pages = result.getPages();     //总页数
        List<Spu> list = result.getRecords();  //查询到的spu集合
        // 5.转换DTO
        List<SpuDTO> dtoList = SpuDTO.convertEntityList(list);
        for (SpuDTO spuDTO : dtoList) {
            // 查询spu的分类和品牌的名称
            handleCategoryAndBrandName(spuDTO);
        }

        // 6.封装分页结果并返回
        return new PageDTO<>(total, pages, dtoList);
    }

    @Override
    @Transactional
    public void updateSpuSaleable(Long id, Boolean saleable) {
        Spu spu = new Spu();
        spu.setId(id);
        spu.setSaleable(saleable);
        boolean success = updateById(spu);
        if (!success) {
            throw new LyException(500, "更新失败");
        }
        // 2.更新sku
        success = skuService.update().eq("spu_id", id).set("saleable", saleable).update();
        if (!success) {
            throw new LyException(500, "更新失败");
        }

        String routingkey = saleable ? "up" : "down";
        this.amqpTemplate.convertAndSend("jhj", routingkey,spu.getId());


    }

    @Override
    public SpuDTO queryGoodsById(Long id) {
        //查询商品 包含商品基本信息  skus  spuDetail  全部封装到SpuDTO
        Spu spu = getById(id);
        if (spu == null) {
            throw new LyException(400, "商品id不存在！");
        }
        SpuDTO spuDTO = new SpuDTO(spu);
        //查询skus
        List<Sku> skus = skuService.query().eq("spu_id", id).list();
        List<SkuDTO> skuDTOS = SkuDTO.convertEntityList(skus);
        spuDTO.setSkus(skuDTOS);

        //查询spuDetail
        SpuDetail detail = detailService.getById(id);
        if (detail == null) {
            throw new LyException(400, "商品id不存在！");
        }
        SpuDetailDTO spuDetailDTO = new SpuDetailDTO(detail);
        spuDTO.setSpuDetail(spuDetailDTO);
        // 4.准备商品分类和品牌名称
        handleCategoryAndBrandName(spuDTO);
        return spuDTO;
    }

    @Override
    @Transactional
    public void addGoods(SpuDTO spuDTO) {
        //添加商品需要添加ppu+sku+SpuDetail

        Spu spu = spuDTO.toEntity(Spu.class);
        //先添加分类spu    商品详细SpuDetail   商品sku
        boolean save = spuService.save(spu);
        if (!save) {
            throw new LyException(500, "新增商品失败");
        }

        SpuDetailDTO spuDetail = spuDTO.getSpuDetail();
        SpuDetail spuDetail1 = spuDetail.toEntity(SpuDetail.class);
        spuDetail1.setSpuId(spu.getId());
        boolean save1 = detailService.save(spuDetail1);
        spuDetail.setSpuId(spu.getId());
        if (!save1) {
            throw new LyException(500, "新增详细信息失败");
        }

        List<SkuDTO> skus = spuDTO.getSkus();
        List<Sku> list = skus.stream().map(skuDTO -> {
            Sku sku = skuDTO.toEntity(Sku.class);
            sku.setSaleable(false);
            sku.setSpuId(spu.getId());
            return sku;
        }).collect(Collectors.toList());
        // 批量新增
        skuService.saveBatch(list);

    }

    @Override
    public void updateGoods(SpuDTO spuDTO) {
        //SpuDTO中包含了 spu sku  spuDetail  需要一个一个判断是否存在 然后修改
        Long spuDTOid = spuDTO.getId();
        if (spuDTOid != null) {
            //需要修改
            Spu spu = spuDTO.toEntity(Spu.class);
            // 1.3.更新
            boolean success = updateById(spu);
            if (!success) {
                // 更新失败，抛出异常
                throw new LyException(500, "更新商品失败！");
            }
        }
        //spuDetail
        SpuDetailDTO spuDetail = spuDTO.getSpuDetail();
        if (spuDetail != null && spuDetail.getSpuId() != null) {
            boolean b = detailService.updateById(spuDetail.toEntity(SpuDetail.class));
            if (!b) {
                // 更新失败，抛出异常
                throw new LyException(500, "更新商品失败！");
            }
        }
        //sku
        List<SkuDTO> dtoList = spuDTO.getSkus();
        if (CollectionUtils.isEmpty(dtoList)) {
            return;
        }


        // 3.2.转换DTO，并将sku根据saleable是否为null来分组。null，是新增或修改，不是null是删除
        Map<Boolean, List<Sku>> map = dtoList.stream()
                .map(skuDTO -> skuDTO.toEntity(Sku.class))
                .collect(Collectors.groupingBy(sku -> sku.getSaleable() == null));

        // 3.3.获取要新增或修改的sku
        List<Sku> insertOrUpdateList = map.get(true);
        // 如果不为空，则修改或新增
        if (!CollectionUtils.isEmpty(insertOrUpdateList)) {
            skuService.saveOrUpdateBatch(insertOrUpdateList);
        }

        // 3.4.获取要删除的sku
        List<Sku> deleteSkuList = map.get(false);
        if (!CollectionUtils.isEmpty(deleteSkuList)) {
            // 存在要删除的sku
            List<Long> idList = deleteSkuList.stream().map(Sku::getId).collect(Collectors.toList());
            // 删除
            skuService.removeByIds(idList);
        }

    }


    private void handleCategoryAndBrandName(SpuDTO spuDTO) {
        // 根据品牌id查询品牌名称
        Brand brand = brandService.getById(spuDTO.getBrandId());
        if (brand != null) {
            spuDTO.setBrandName(brand.getName());
        }
        // 根据三级分类id查询分类集合
        List<Category> categories = categoryService.listByIds(spuDTO.getCategoryIds());
        if (!CollectionUtils.isEmpty(categories)) {
            // 取出分类的名称，拼接起来
            String names = categories.stream().map(Category::getName).collect(Collectors.joining("/"));
            spuDTO.setCategoryName(names);
        }
    }
}
